/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package com.inspur.edp.lcm.metadata.common;

import com.fasterxml.jackson.databind.JsonNode;
import com.inspur.edp.lcm.metadata.api.service.FileService;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

/**
 * 文件服务实现类
 *
 * @author zhaoleitr
 */
@Slf4j
public class FileServiceImp implements FileService {

    /**
     * 文件删除操作
     *
     * @param fullPath 文件路径
     */
    @Override
    public void fileDelete(String fullPath) throws IOException {
        File file = new File(fullPath);
        if (!file.isFile()) {
            final String message =
                    "This is not a file " + fullPath + ".";
            throw new IOException(message);
        }
        file.delete();
    }

    /**
     * 文件更新操作
     *
     * @param fullPath 文件路径
     * @param content  文件内容
     */
    @Override
    public void fileUpdate(String fullPath, String content) {
        try {
            byte[] buffer = content.getBytes(StandardCharsets.UTF_8);
            FileOutputStream fos = new FileOutputStream(fullPath, true);
            fos.write(buffer);
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件更新
     *
     * @param fullPath
     * @param content  文件内容
     * @param append   是否追加
     */
    @Override
    public void fileUpdate(String fullPath, String content, boolean append) {
        try {
            byte[] buffer = content.getBytes(StandardCharsets.UTF_8);
            FileOutputStream fos = new FileOutputStream(fullPath, append);
            fos.write(buffer);
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 判断文件是否存在
     *
     * @param fullPath 文件路径
     * @return 文件存在返回true，不存在返回false
     */
    @Override
    public boolean isFileExist(String fullPath) {
        File file = new File(fullPath);
        return file.isFile();
    }

    /**
     * 文件重命名操作
     *
     * @param oldFileName 旧文件名
     * @param newFileName 新文件名
     */
    @Override
    public void fileRename(String oldFileName, String newFileName) throws IOException {
        File oldfile = new File(oldFileName);
        if (oldfile.isFile()) {
            if (newFileName == null || newFileName.length() <= 0) {
                return;
            }
            if (!(oldfile.renameTo(new File(newFileName)))) {
                final String message =
                        "Can not rename file " + "old name: " + oldFileName + " new name: " + newFileName + ".";
                throw new IOException(message);
            }
        }
    }

    /**
     * 读取文件内容，返回文件内容的字符串。
     *
     * @param path 文件路径
     * @return 文件内容字符串
     */
    @Override
    public String fileRead(String path) {
        String encoding = "UTF-8";
        File file = new File(path);
        if (!file.exists()) {
            throw new RuntimeException("文件不存在：" + path);
        }
        long fileLength = file.length();
        String fileContents = null;
        try {
            byte[] bytes = new byte[(int) fileLength];
            FileInputStream in = new FileInputStream(file);
            in.read(bytes);
            in.close();

            //判断有没有utf-8 bom头。有则去除。
            fileContents = new String(bytes, encoding);
            if (fileContents.startsWith("\ufeff")) {
                fileContents = fileContents.substring(1);
            }
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("读取文件失败：" + path + "，系统不支持此编码：" + encoding, e);
        } catch (IOException e) {
            throw new RuntimeException("读取文件失败：" + path, e);
        }
        return fileContents;
    }

    /**
     * 文件拷贝
     *
     * @param sourcePath      原路径
     * @param destinationPath 目标路径
     */
    @Override
    public void fileCopy(String sourcePath, String destinationPath) throws IOException {
        if (sourcePath != null && destinationPath != null) {
            Files.copy(Paths.get(sourcePath), Paths.get(destinationPath), REPLACE_EXISTING);
        }
    }

    /**
     * 文件目录是否存在
     *
     * @param path 文件夹路径
     * @return 文件夹存在，返回true，否则返回false
     */
    @Override
    public boolean isDirectoryExist(String path) {
        return (new File(path)).isDirectory();
    }

    /**
     * 获取所有目录
     *
     * @param path 文件夹路径
     * @return 文件夹下所有文件目录
     */
    @Override
    public List<File> getDirectorys(String path) {
        //初始化制定路径
        File file = new File(path);
        List<File> fileList = new ArrayList<>();
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files != null) {
                for (File value : files) {
                    if (value.isDirectory()) {
                        fileList.add(value);
                    }
                }
            }
        }
        return fileList;
    }

    /**
     * 返回某一文件夹下的所有文件，如果这个路径下没有文件，那么返回空list由调用者进行判断处理
     *
     * @param path 文件夹路径
     * @return 文件夹下所有文件
     */
    @Override
    public List<File> getAllFiles(String path) {
        List<File> filesInFolder = new ArrayList<>();
        File file = new File(path);
        // 如果这个路径下没有文件，那么返回空list由调用者进行判断处理
        File[] allfiles = file.listFiles();
        if (allfiles == null) {
            return filesInFolder;
        }
        for (File f : allfiles) {
            if (f.isFile()) {
                filesInFolder.add(f);
            }
        }
        return filesInFolder;
    }

    /**
     * 获取路径下的所有文件/文件夹
     *
     * @param directoryPath 需要遍历的文件夹路径
     * @param isRecursively 是否递归查找
     * @return
     */
    public static List<File> getAllFiles(String directoryPath, boolean isRecursively) {
        List<File> list = new ArrayList<>();
        File baseFile = new File(directoryPath);
        if (baseFile.isFile() || !baseFile.exists()) {
            return list;
        }
        File[] files = isRecursively ? baseFile.listFiles() : baseFile.listFiles(File::isFile);
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    list.addAll(getAllFiles(file.getAbsolutePath(), true));
                } else {
                    list.add(file);
                }
            }
        }
        return list;
    }

    /**
     * 列出所有文件
     *
     * @param dirFile
     * @param filter
     * @return
     */
    public static List<File> listAllFiles(File dirFile, FileFilter filter) {
        List<File> files = new ArrayList<>();
        if (dirFile == null) {
            return files;
        }
        File[] fileArr = dirFile.listFiles(filter);
        if (fileArr != null) {
            files.addAll(Arrays.asList(fileArr));
        }
        File[] dirs = dirFile.listFiles(File::isDirectory);
        if (dirs != null && dirs.length > 0) {
            for (File dir : dirs) {
                files.addAll(listAllFiles(dir, filter));
            }
        }
        return files;
    }

    /**
     * 获取文件列表
     *
     * @param dirFile
     * @param filter
     * @return
     */
    public static List<File> listAllFilesFilterDirAndFile(File dirFile, FilenameFilter filter) {
        List<File> files = new ArrayList<>();
        if (dirFile == null || !dirFile.exists()) {
            return files;
        }
        File[] sonFiles = dirFile.listFiles(filter);
        if (sonFiles == null) {
            return files;
        }
        for (File sonFile : sonFiles) {
            // 不添加隐藏文件
            if (sonFile.getName().startsWith(".")) {
                continue;
            }
            if (sonFile.isFile()) {
                files.add(sonFile);
            } else {
                files.addAll(listAllFilesFilterDirAndFile(sonFile, filter));
            }
        }
        return files;
    }

    /**
     * 创建文件夹
     *
     * @param dirPath 文件夹路径
     */
    @Override
    public void createDirectory(String dirPath) {
        File file = new File(dirPath);
        file.mkdirs();
    }

    /**
     * 删除某文件夹下的所有文件以及文件夹
     * 1.是文件：则删除
     * 2.是目录：则“自动”递归删除指定目录下的所有文件和文件夹
     *
     * @param dirPath 文件或文件夹路径
     */
    @Override
    public void deleteAllFilesUnderDirectory(String dirPath) throws IOException {
        File file = new File(dirPath);
        forceDelete(file);
    }

    /**
     * 强制删除文件
     *
     * @param file
     * @throws IOException
     */
    private static void forceDelete(final File file) throws IOException {
        if (file.isDirectory()) {
            deleteDirectory(file);
        } else {
            final boolean filePresent = file.exists();
            if (!file.delete()) {
                if (!filePresent) {
                    throw new FileNotFoundException("File does not exist: " + file);
                }
                final String message = "Unable to delete file: " + file;
                throw new IOException(message);
            }
        }
    }

    /**
     * 是否为软链接
     *
     * @param file
     * @return
     * @throws IOException
     */
    private static boolean isSymlink(final File file) throws IOException {
        Path path = file.toPath().toRealPath();
        return !path.equals(file.toPath().toAbsolutePath());
    }

    /**
     * 递归删除文件夹
     *
     * @param directory 文件夹路径
     */
    private static void deleteDirectory(final File directory) throws IOException {
        if (!directory.exists()) {
            return;
        }
        if (isSymlink(directory)) {
            directory.delete();
            return;
        }

        cleanDirectory(directory);

        if (!directory.delete()) {
            deleteByDos(directory.getAbsolutePath());
        }

        if (directory.exists()) {
            final String message =
                    "Unable to delete directory " + directory + ".";
            throw new IOException(message);
        }
    }

    /**
     * 清理文件目录
     *
     * @param directory
     * @throws IOException
     */
    public static void cleanDirectory(final File directory) throws IOException {
        final File[] files = verifiedListFiles(directory);

        IOException exception = null;
        for (final File file : files) {
            try {
                forceDelete(file); // 强制删除
            } catch (final IOException ioe) {
                exception = ioe;
            }
        }

        if (null != exception) {
            throw exception;
        }
    }

    /**
     * 目录下的文件列表
     *
     * @param directory
     * @return
     * @throws IOException
     */
    private static File[] verifiedListFiles(final File directory) throws IOException {
        if (!directory.exists()) {
            final String message = directory + " does not exist";
            throw new IllegalArgumentException(message);
        }

        if (!directory.isDirectory()) {
            final String message = directory + " is not a directory";
            throw new IllegalArgumentException(message);
        }

        final File[] files = directory.listFiles();
        // null if security restricted
        if (files == null) {
            throw new IOException("Failed to list contents of " + directory);
        }
        return files;
    }

    /**
     * 整合路径
     *
     * @param path1 path1
     * @param path2 path2
     * @return 整合后路径
     */
    @Override
    public String getCombinePath(String path1, String path2) {
        String path = Paths.get(path1).resolve(path2).normalize().toString();
        return handlePath(path);
    }

    /**
     * 获取后缀信息
     *
     * @param path 文件路径
     * @return
     */
    @Override
    public String getExtension(String path) {
        File file = new File(path);
        return getExtension(file);
    }

    /**
     * 获取后缀信息
     *
     * @param path 文件
     * @return 文件后缀
     */
    @Override
    public String getExtension(File path) {
        if (path.isDirectory()) {
            final String message = path + " is a directory";
            throw new IllegalArgumentException(message);
        }
        String fileName = path.getName();
        int point = fileName.lastIndexOf('.');
        int length = fileName.length();
        if (point == -1 || point == length - 1) {
            return "";
        } else {
            return fileName.substring(point, length);
        }
    }

    /**
     * 获取无后缀的路径信息
     *
     * @param path 文件路径
     * @return 无后缀的路径信息
     */
    @Override
    public String getFileNameWithoutExtension(String path) {
        path = handlePath(path);
        File file = new File(path);
        return getFileNameWithoutExtension(file);
    }

    /**
     * 获取无后缀的路径信息
     *
     * @param path 路径信息
     * @return 无后缀的路径信息
     */
    @Override
    public String getFileNameWithoutExtension(File path) {
        if (path.isDirectory()) {
            final String message = path + " is  a directory";
            throw new IllegalArgumentException(message);
        }
        String fileName = path.getName();
        int point = fileName.lastIndexOf('.');
        if (point == -1) {
            return fileName;
        } else {
            return fileName.substring(0, point);
        }
    }

    /**
     * 创建文件
     *
     * @param path     文件路径
     * @param filename 文件名
     */
    @Override
    public void createFile(String path, String filename) {
        String filePath = path + File.separator + filename;
        createFile(filePath);
    }

    /**
     * 创建文件
     *
     * @param filePath 文件详细路径
     */
    @Override
    public void createFile(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 文件名称
     *
     * @param path 文件路径
     * @return 文件名称
     */
    @Override
    public String getFileName(String path) {
        return (new File(path)).getName();
    }

    /**
     * 获取路径名
     *
     * @param path 文件夹路径
     * @return 文件夹名
     */
    @Override
    public String getDirectoryName(String path) {
        return (new File(path)).getParent();
    }

    /**
     * 获取目录分隔符
     *
     * @return 目录分隔符
     */
    @Override
    public char getDirectorySeparatorChar() {
        return File.separatorChar;
    }

    /**
     * 删除文件目录
     *
     * @param fullPath
     * @return
     * @throws IOException
     */
    @Override
    public boolean deleteDirectory(String fullPath) throws IOException {
        File file = new File(fullPath);
        if (!file.isDirectory()) {
            final String message =
                    "This is not a Directory " + fullPath + ".";
            throw new IOException(message);
        }
        return file.delete();
    }

    /**
     * 重命名文件目录
     *
     * @param fromDir 要重命名的目录
     * @param toDir   重命名后的目录
     * @return
     * @throws IOException
     */
    @Override
    public boolean renameDirectory(String fromDir, String toDir) throws IOException {
        File from = new File(fromDir);
        if ((!from.exists() || !from.isDirectory())) {
            final String message =
                    "Directory does not exist: " + fromDir;
            throw new IOException(message);
        }
        File to = new File(toDir);
        return from.renameTo(to);
    }

    /**
     * 强制移动文件目录
     *
     * @param fromDir 要移动的文件夹路径
     * @param toDir   移动文件夹路径
     * @return
     * @throws IOException
     */
    @Override
    public Path forceMoveDir(String fromDir, String toDir) throws IOException {
        Path fromPath = Paths.get(fromDir);
        Path toPath = Paths.get(toDir);
        return Files.move(fromPath, toPath.resolve(fromPath.getFileName()), REPLACE_EXISTING);
    }

    /**
     * 获取项目路径
     *
     * @param proPath 路径信息
     * @return 工程路径
     */
    @Override
    public String getProjectPath(String proPath) {
        if (!proPath.endsWith("java")) {
            proPath = proPath + "/java";
        }
        // java目录下进行判断。
        File file = new File(proPath);
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files == null || files.length == 0) {
                return null;
            }
            // 遍历java目录下目录
            for (File value : files) {
                // 对目录进行判断
                if (value.isDirectory()) {
                    File[] fileInPoject = value.listFiles();
                    if (fileInPoject != null) {
                        for (File file1 : fileInPoject) {
                            if (file1.isFile() && file1.toString().contains("pom.xml")) {
                                return file1.getParent().substring(file1.toString().indexOf("java"));
                            }
                        }
                    }
                }
            }
        }
        return null;
    }

    /**
     * 获取JAR路径
     *
     * @param proPath
     * @return
     */
    @Override
    public List<String> getJarPath(String proPath) {
        if (!proPath.endsWith("java")) {
            proPath = proPath + "/java";
        }
        Path path = Paths.get(proPath);
        List<String> filename = new ArrayList<>();
        try {
            Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
                        // 访问文件时触发
                        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
                            if (file.toString().endsWith(".jar")) {
                                String filepaths = file.toString();
                                if (filepaths.contains("out") || filepaths.contains("target")) {
                                    filename.add(handlePath(filepaths.substring(filepaths.indexOf("java"))));
                                }
                                return FileVisitResult.CONTINUE;
                            }
                            return FileVisitResult.CONTINUE;
                        }
                    });
        } catch (IOException e) {
            e.printStackTrace();
        }
        Collections.sort(filename);
        return filename;
    }

    @Override
    public String getApiModulePath(String proPath) {
        if (!proPath.endsWith("java")) {
            proPath = proPath + "/java";
        }
        //java目录下进行判断。
        File file = new File(proPath);
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            if (files == null || files.length == 0) {
                return null;
            }
            //遍历java目录下目录
            for (File value : files) {
                //对目录进行判断
                if (value.isDirectory()) {
                    File[] fileInPoject = value.listFiles();
                    if (fileInPoject != null) {
                        for (File file1 : fileInPoject) {
                            if (file1.isDirectory() && file1.toString().endsWith("api")) {
                                return handlePath(file1.toString());
                            }
                        }
                    }
                }
            }
        }
        return null;
    }

    /**
     * 处理路径
     *
     * @param path
     * @return
     */
    public static String handlePath(String path) {
        return path.replace("\\", "/");
    }

    /**
     * 将指定的zip文件解压到指定目录下，其中：zipName：文件名，targetDirName：需解压到的目录
     *
     * @param zipName       被解压的zip包名
     * @param targetDirName 解压目标目录
     * @throws ZipException
     */
    @Override
    public void upzipFile(String zipName, String targetDirName) throws ZipException {
        if (!targetDirName.endsWith(File.separator)) {
            targetDirName += File.separator;
        }
        try {
            // 根据zip文件创建ZipFile对象，此类的作用是从zip文件读取条目
            ZipFile zipFile = new ZipFile(targetDirName + "/" + zipName);
            ZipEntry zn;
            String entryName;
            String targetFileName;
            byte[] buffer = new byte[4096];
            int bytes_read;
            Enumeration<? extends ZipEntry> entrys = zipFile.entries();            // 获取ZIP文件里所有的文件条目的名字
            while (entrys.hasMoreElements()) {                // 循环遍历所有的文件条目的名字
                zn = entrys.nextElement();
                entryName = zn.getName();                // 获得每一条文件的名字
                targetFileName = targetDirName + entryName;
                if (zn.isDirectory()) {
                    new File(targetFileName).mkdirs();        // 如果zn是一个目录，则创建目录
                    continue;
                } else {
                    new File(targetFileName).getParentFile().mkdirs();// 如果zn是文件，则创建父目录
                }
                File targetFile = new File(targetFileName);    // 否则创建文件
//                System.out.println("正在创建文件：" + targetFile.getAbsolutePath());
                FileOutputStream os = new FileOutputStream(targetFile);// 打开文件输出流
                InputStream is = zipFile.getInputStream(zn);    // 从ZipFile对象中打开entry的输入流
                while ((bytes_read = is.read(buffer)) != -1) {
                    os.write(buffer, 0, bytes_read);
                }
                os.close();                                // 关闭流
                is.close();
            }
//            System.out.println("解压缩"+zipName+"成功！");
        } catch (IOException err) {
            throw new RuntimeException("解压缩" + zipName + "失败: " + err.getMessage(), err);
        }
    }

    @Override
    public List<String> getAllProjectsDirectories(String path, List<String> projectsList, String proFlag) {
        File[] files = (new File(path)).listFiles();
        if (files == null) {
            return projectsList;
        }
        for (File file : files) {
            if (file.isFile() &&
                    file.getName().equals(proFlag)) {
                projectsList.add(file.getParent());
            }

            if (file.isDirectory() && (!"node_modules".equals(file.getName()) ||
                    !"packages".equals(file.getName()) || !"maven".equals(file.getName()))) {
                getAllProjectsDirectories(file.getAbsolutePath(), projectsList, proFlag);
            }
        }
        return projectsList;
    }

    @Override
    public void folderCopy(String sourcePath, String destinationPath) {
        try {
            (new File(destinationPath)).mkdirs();
            File souceFile = new File(sourcePath);
            String[] file = souceFile.list();
            File temp;
            if (file == null) {
                return;
            }
            for (String s : file) {
                if (sourcePath.endsWith(File.separator)) {
                    temp = new File(sourcePath + s);
                } else {
                    temp = new File(sourcePath + File.separator + s);
                }

                if (temp.isFile()) {
                    FileInputStream input = new FileInputStream(temp);

                    FileOutputStream output = new FileOutputStream(destinationPath + File.separator + temp.getName());
                    byte[] b = new byte[5120];
                    int len;
                    while ((len = input.read(b)) != -1) {
                        output.write(b, 0, len);
                    }
                    output.flush();
                    output.close();
                    input.close();
                    updateLastModified(destinationPath + File.separator + temp.getName(), temp.lastModified());
                }
                if (temp.isDirectory()) {
                    folderCopy(sourcePath + File.separator + s, destinationPath + File.separator + s);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("复制目录出错！", e);
        }
    }

    private void updateLastModified(String filePath, long lastModified) {
        new File(filePath).setLastModified(lastModified);
    }

    public boolean startWith(String a, String b) {
        if (a == null || b == null) {
            return false;
        }
        a = ServiceUtils.handlePath(a).replace("//", "/");
        b = ServiceUtils.handlePath(b).replace("//", "/");
        if (a.indexOf(':') > -1 && b.indexOf(':') > -1) {
            if (a.substring(0, 1).equalsIgnoreCase(b.substring(0, 1))) {
                a = a.substring(a.indexOf(':') + 1);
                b = b.substring(b.indexOf(':') + 1);
            } else {
                return false;
            }
        } else if (a.indexOf(':') > -1) {
            a = a.substring(a.indexOf(':') + 1);
        } else if (b.indexOf(':') > -1) {
            b = b.substring(b.indexOf(':') + 1);
        }
        return a.startsWith(b);
    }

    /**
     * 获取相对路径
     *
     * @param a
     * @param b
     * @return
     */
    public static String getRelativePath(String a, String b) {
        a = ServiceUtils.handlePath(a).replace("//", "/");
        b = ServiceUtils.handlePath(b).replace("//", "/");

        if (a.indexOf(':') > -1) {
            a = a.substring(a.indexOf(':') + 1);
        }
        if (a.endsWith("/")) {
            a = a.substring(0, a.length() - 1);
        }

        if (b.indexOf(':') > -1) {
            b = b.substring(b.indexOf(':') + 1);
        }
        if (b.endsWith("/")) {
            b = b.substring(0, b.length() - 1);
        }
        if (a.length() <= b.length()) {
            return "";
        }
        return a.substring(b.length() + 1);
    }

    /**
     * 用DOS命令删除
     *
     * @param path
     */
    private static void deleteByDos(String path) {
        String osName = System.getProperty("os.name");
        if (osName.contains("Windows")) {
            try {
                String cmd = "cmd /c rd /s/q " + path;
                Process p = Runtime.getRuntime().exec(cmd);
                p.waitFor();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static String combinePath(String startPath, String... paths) {
        Path combinedPath = Paths.get(startPath);
        for (String path : paths) {
            combinedPath = combinedPath.resolve(path);
        }
        return combinedPath.normalize().toString().replace("\\", "/");
    }

    public static JsonNode readSection(String filePath, String sectionName) {
        String fileContents = new FileServiceImp().fileRead(filePath);
        JsonNode jsonNode;
        try {
            jsonNode = ServiceUtils.getMapper().readTree(fileContents);
        } catch (Exception e) {
            throw new RuntimeException("反序列化文件内容失败：" + filePath, e);
        }
        return jsonNode.findValue(sectionName);
    }

    /**
     * 创建目录和文件夹
     *
     * @param filePath
     */
    public static void createDirAndFile(String filePath) {
        File file = new File(filePath);
        if (file.exists()) {
            return;
        }
        File parentFile = file.getParentFile();
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }
        try {
            file.createNewFile();
        } catch (IOException e) {
            throw new RuntimeException("创建文件失败：" + filePath + "，" + e.getMessage(), e);
        }
    }

    /**
     * 是否相同
     *
     * @param a
     * @param b
     * @return
     */
    public static boolean isEqual(String a, String b) {
        try {
            return new File(a).getCanonicalPath().equals(new File(b).getCanonicalPath());
        } catch (IOException e) {
            throw new RuntimeException("路径无效：" + a + "," + b, e);
        }
    }
}
